<template>
    <view id="list" ref="list" class="uni-indexed-list">
        <!-- #ifdef APP-NVUE -->
        <list class="uni-indexed-list__scroll" scrollable="true" show-scrollbar="false">
            <cell v-for="(list, idx) in lists" :key="idx" :ref="'uni-indexed-list-' + idx">
                <!-- #endif -->
                <!-- #ifndef APP-NVUE -->
                <scroll-view :scroll-into-view="scrollViewId" class="uni-indexed-list__scroll" scroll-y>
                    <view v-for="(list, idx) in lists" :id="'uni-indexed-list-' + idx" :key="idx">
                        <!-- #endif -->
                        <indexed-list-item
                            :list="list"
                            :loaded="loaded"
                            :idx="idx"
                            :show-select="showSelect"
                            @item-click="onClick"
                        ></indexed-list-item>
                        <!-- #ifndef APP-NVUE -->
                    </view>
                </scroll-view>
                <!-- #endif -->
                <!-- #ifdef APP-NVUE -->
            </cell>
        </list>
        <!-- #endif -->
        <view
            class="uni-indexed-list__menu"
            @touchstart="touchStart"
            @touchmove.stop.prevent="touchMove"
            @touchend="touchEnd"
            @mousedown.stop="mousedown"
            @mousemove.stop.prevent="mousemove"
            @mouseleave.stop="mouseleave"
        >
            <view
                v-for="(list, key) in lists"
                :key="key"
                class="uni-indexed-list__menu-item"
                :class="touchmoveIndex == key ? 'uni-indexed-list__menu--active' : ''"
            >
                <text
                    class="uni-indexed-list__menu-text"
                    :class="touchmoveIndex == key ? 'uni-indexed-list__menu-text--active' : ''"
                    >{{ list.key }}</text
                >
            </view>
        </view>
        <view v-if="touchmove" class="uni-indexed-list__alert-wrapper">
            <text class="uni-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text>
        </view>
    </view>
</template>
<script>
import indexedListItem from "./uni-indexed-list-item.vue";
// #ifdef APP-NVUE
const dom = weex.requireModule("dom");
// #endif
// #ifdef APP-PLUS
function throttle(func, delay) {
    var prev = Date.now();
    return function () {
        var context = this;
        var args = arguments;
        var now = Date.now();
        if (now - prev >= delay) {
            func.apply(context, args);
            prev = Date.now();
        }
    };
}

function touchMove(e) {
    let pageY = e.touches[0].pageY;
    let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight);
    if (this.touchmoveIndex === index) {
        return false;
    }
    let item = this.lists[index];
    if (item) {
        // #ifndef APP-NVUE
        this.scrollViewId = "uni-indexed-list-" + index;
        this.touchmoveIndex = index;
        // #endif
        // #ifdef APP-NVUE
        dom.scrollToElement(this.$refs["uni-indexed-list-" + index][0], {
            animated: false
        });
        this.touchmoveIndex = index;
        // #endif
    }
}
const throttleTouchMove = throttle(touchMove, 40);
// #endif

/**
 * IndexedList 索引列表
 * @description 用于展示索引列表
 * @tutorial https://ext.dcloud.net.cn/plugin?id=375
 * @property {Boolean} showSelect = [true|false] 展示模式
 * 	@value true 展示模式
 * 	@value false 选择模式
 * @property {Object} options 索引列表需要的数据对象
 * @event {Function} click 点击列表事件 ，返回当前选择项的事件对象
 * @example <uni-indexed-list options="" showSelect="false" @click=""></uni-indexed-list>
 */
export default {
    name: "UniIndexedList",
    components: {
        indexedListItem
    },
    props: {
        options: {
            type: Array,
            default() {
                return [];
            }
        },
        showSelect: {
            type: Boolean,
            default: false
        }
    },
    emits: ["click"],
    data() {
        return {
            lists: [],
            winHeight: 0,
            itemHeight: 0,
            winOffsetY: 0,
            touchmove: false,
            touchmoveIndex: -1,
            scrollViewId: "",
            touchmovable: true,
            loaded: false,
            isPC: false
        };
    },
    watch: {
        options: {
            handler: function () {
                this.setList();
            },
            deep: true
        }
    },
    mounted() {
        // #ifdef H5
        this.isPC = this.IsPC();
        // #endif
        setTimeout(() => {
            this.setList();
        }, 50);
        setTimeout(() => {
            this.loaded = true;
        }, 300);
    },
    methods: {
        setList() {
            let index = 0;
            this.lists = [];
            this.options.forEach((value, index) => {
                if (value.data.length === 0) {
                    return;
                }
                let indexBefore = index;
                let items = value.data.map((item) => {
                    let obj = {};
                    obj["key"] = value.letter;
                    obj["name"] = item;
                    obj["itemIndex"] = index;
                    index++;
                    obj.checked = item.checked ? item.checked : false;
                    return obj;
                });
                this.lists.push({
                    title: value.letter,
                    key: value.letter,
                    items: items,
                    itemIndex: indexBefore
                });
            });
            // #ifndef APP-NVUE
            uni.createSelectorQuery()
                .in(this)
                .select("#list")
                .boundingClientRect()
                .exec((ret) => {
                    this.winOffsetY = ret[0].top;
                    this.winHeight = ret[0].height;
                    this.itemHeight = this.winHeight / this.lists.length;
                });
            // #endif
            // #ifdef APP-NVUE
            dom.getComponentRect(this.$refs["list"], (res) => {
                this.winOffsetY = res.size.top;
                this.winHeight = res.size.height;
                this.itemHeight = this.winHeight / this.lists.length;
            });
            // #endif
        },
        touchStart(e) {
            this.touchmove = true;
            let pageY = this.isPC ? e.pageY : e.touches[0].pageY;
            let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight);
            let item = this.lists[index];
            if (item) {
                this.scrollViewId = "uni-indexed-list-" + index;
                this.touchmoveIndex = index;
                // #ifdef APP-NVUE
                dom.scrollToElement(this.$refs["uni-indexed-list-" + index][0], {
                    animated: false
                });
                // #endif
            }
        },
        touchMove(e) {
            // #ifndef APP-PLUS
            let pageY = this.isPC ? e.pageY : e.touches[0].pageY;
            let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight);
            if (this.touchmoveIndex === index) {
                return false;
            }
            let item = this.lists[index];
            if (item) {
                this.scrollViewId = "uni-indexed-list-" + index;
                this.touchmoveIndex = index;
            }
            // #endif
            // #ifdef APP-PLUS
            throttleTouchMove.call(this, e);
            // #endif
        },
        touchEnd() {
            this.touchmove = false;
            // this.touchmoveIndex = -1
        },

        /**
         * 兼容 PC @tian
         */

        mousedown(e) {
            if (!this.isPC) return;
            this.touchStart(e);
        },
        mousemove(e) {
            if (!this.isPC) return;
            this.touchMove(e);
        },
        mouseleave(e) {
            if (!this.isPC) return;
            this.touchEnd(e);
        },

        // #ifdef H5
        IsPC() {
            var userAgentInfo = navigator.userAgent;
            var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
            var flag = true;
            for (let v = 0; v < Agents.length - 1; v++) {
                if (userAgentInfo.indexOf(Agents[v]) > 0) {
                    flag = false;
                    break;
                }
            }
            return flag;
        },
        // #endif

        onClick(e) {
            let { idx, index } = e;
            let obj = {};
            for (let key in this.lists[idx].items[index]) {
                obj[key] = this.lists[idx].items[index][key];
            }
            let select = [];
            if (this.showSelect) {
                this.lists[idx].items[index].checked = !this.lists[idx].items[index].checked;
                this.lists.forEach((value, idx) => {
                    value.items.forEach((item, index) => {
                        if (item.checked) {
                            let obj = {};
                            for (let key in this.lists[idx].items[index]) {
                                obj[key] = this.lists[idx].items[index][key];
                            }
                            select.push(obj);
                        }
                    });
                });
            }
            this.$emit("click", {
                item: obj,
                select: select
            });
        }
    }
};
</script>
<style lang="scss" scoped>
.uni-indexed-list {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
}

.uni-indexed-list__scroll {
    flex: 1;
}

.uni-indexed-list__menu {
    width: 24px;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: column;
}

.uni-indexed-list__menu-item {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex: 1;
    align-items: center;
    justify-content: center;
    /* #ifdef H5 */
    cursor: pointer;
    /* #endif */
}

.uni-indexed-list__menu-text {
    font-size: 12px;
    text-align: center;
    color: #aaa;
}

.uni-indexed-list__menu--active {
    // background-color: rgb(200, 200, 200);
}

.uni-indexed-list__menu--active {
}

.uni-indexed-list__menu-text--active {
    border-radius: 16px;
    width: 16px;
    height: 16px;
    line-height: 16px;
    background-color: #007aff;
    color: #fff;
}

.uni-indexed-list__alert-wrapper {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    align-items: center;
    justify-content: center;
}

.uni-indexed-list__alert {
    width: 80px;
    height: 80px;
    border-radius: 80px;
    text-align: center;
    line-height: 80px;
    font-size: 35px;
    color: #fff;
    background-color: rgba(0, 0, 0, 0.5);
}
</style>
